import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

# 图像阈值
# 这种阈值处理的方法是简单易懂的。如果像素值大于阈值，则为其分配一个值（可以是白色），否则为其分配另一个值（可以是黑色）。
# 使用的函数是cv.threshold。
# 函数第一个参数是源图像，它应该是灰度图像。
# 第二个参数是用于对像素值进行分类的阈值。
# 第三个参数是maxVal，它表示如果像素值大于（有时小于）阈值则要给出的值。
# OpenCV提供不同类型的阈值，由函数的第四个参数决定。不同的类型有：
#
# cv.THRESH_BINARY 二值化
# cv.THRESH_BINARY_INV  二值取反
# cv.THRESH_TRUNC 截断阈值化处理会将图像中大于阈值的像素点的值设定为阈值，小于或等于该阈值的像素点的值保持不变
# cv.THRESH_TOZERO 低阈值零处理会将图像中小于或等于阈值的像素点的值处理为0，大于阈值的像素点的值保持不变
# cv.THRESH_TOZERO_INV  超阈值零处理会将图像中大于阈值的像素点的值处理为0，小于或等于该阈值的像素点的值保持不变

# 函数将获得两个输出。第一个是retavl，将在后面解释它的作用。第二个输出是我们的阈值图像。

img = cv.imread("img/cat.jpg", cv.IMREAD_GRAYSCALE)  # 读取灰度图像
img = cv.resize(img, (300, 300))
ret, dis1 = cv.threshold(img, 125, 255, cv.THRESH_BINARY)
ret, dis2 = cv.threshold(img, 125, 255, cv.THRESH_BINARY_INV)
ret, dis3 = cv.threshold(img, 125, 255, cv.THRESH_TRUNC)
ret, dis4 = cv.threshold(img, 125, 255, cv.THRESH_TOZERO)
ret, dis5 = cv.threshold(img, 125, 255, cv.THRESH_TOZERO_INV)

title = ["src img", "THRESH_BINARY", "THRESH_BINARY_INV", "THRESH_TRUNC", "THRESH_TOZERO", "THRESH_TOZERO_INV"]
imgs = [img, dis1, dis2, dis3, dis4, dis5]

# 自适应阈值处理
# def adaptiveThreshold(src: Any,
#                       maxValue: Any,
#                       adaptiveMethod: Any,
#                       thresholdType: Any,
#                       blockSize: Any,
#                       C: Any,
#                       dst: Any = None)
#   Adaptive Method - 自适应方法，决定如何计算阈值。
#     cv.ADAPTIVE_THRESH_MEAN_C：阈值是邻域的平均值。
#     cv.ADAPTIVE_THRESH_GAUSSIAN_C：阈值是邻域值的加权和，其中权重是高斯窗口。
#   Block Size - 邻域大小，它决定了阈值区域的大小。
#   C - 它只是从计算的平均值或加权平均值中减去的常数。
th2 = cv.adaptiveThreshold(img, 255, cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY, 11, 2)
th3 = cv.adaptiveThreshold(img, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 11, 2)
title = ["src img", "THRESH_BINARY", "ADAPTIVE_THRESH_MEAN_C", "ADAPTIVE_THRESH_GAUSSIAN_C"]
imgs = [img, dis1, th2, th3]

# Otsu's 二值化


for i in np.arange(0, len(imgs), 1):
    plt.subplot(2, 3, i + 1), plt.imshow(imgs[i], "gray")
    plt.title(title[i])
    plt.xticks([]), plt.yticks([])
plt.show()

